package cn.angis.db.controller;

import cn.angis.common.model.R;
import cn.angis.common.util.SystemType;
import cn.angis.db.model.DtoInput;
import cn.angis.db.model.PageModel;
import cn.angis.db.model.PageOfResult;
import cn.angis.db.service.BaseService;
import cn.dev33.satoken.sign.SaSignUtil;
import org.beetl.sql.core.page.DefaultPageRequest;
import org.beetl.sql.core.page.PageRequest;
import org.beetl.sql.core.page.PageResult;
import org.beetl.sql.core.query.Query;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.annotation.Post;
import org.noear.solon.data.annotation.Transaction;
import org.noear.solon.validation.annotation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 包名称：cn.angis.db.model
 * 类名称：BaseService
 * 类描述：公共controller
 * 创建人：@author angis.cn
 * 创建日期： 2022/11/28 11:35
 */
@Valid
public abstract class BaseController<Service extends BaseService, T> extends RBaseController {

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Inject
    protected Service baseService;

    /**
     * 转换page
     *
     * @param pageModel model分页数据
     * @param entity  实体数据
     * @return
     */
    protected PageOfResult<T> pageListByEntity(DtoInput entity, PageModel pageModel) {
        PageOfResult<T> pageOfResult = new PageOfResult<>();
        PageRequest request = DefaultPageRequest.of(pageModel.getCurrent(),pageModel.getSize());
        PageResult<T> result = baseService.page(entity, request);
        pageOfResult.setCurrent(pageModel.getCurrent());
        pageOfResult.setPages(result.getTotalPage());
        pageOfResult.setSize(pageModel.getSize());
        pageOfResult.setTotal(result.getTotalRow());
        pageOfResult.setRecords(result.getList());
        return pageOfResult;
    }

    protected PageRequest toPageRequest(PageModel pageModel) {
        return DefaultPageRequest.of(pageModel.getCurrent(),pageModel.getSize());
    }

//    protected <DTO> PageOfResult<DTO> toPageDTO(PageOfResult<T> page, List<DTO> list) {
//        PageOfResult<DTO> pageOfResult = new PageOfResult<>();
//        pageOfResult.setCurrent(page.getCurrent());
//        pageOfResult.setPages(page.getPages());
//        pageOfResult.setSize(page.getSize());
//        pageOfResult.setTotal(page.getTotal());
//        pageOfResult.setRecords(list);
//        return pageOfResult;
//    }

    /**
     * 查询全部
     *
     * @return
     */
    public List<T> allNotDel() {
        return baseService.allNotDel();
    }

    public List<T> all() {
        return baseService.all();
    }


    /**
     * 根据对象id，查询详细信息
     *
     * @param id
     * @return
     */
    public T getById(Serializable id) {
        return (T) baseService.getById(id);
    }

    /**
     * 添加
     *
     * @param entity
     * @return
     */
    public R<Boolean> save(T entity) {
        baseService.save(entity);
        return success(true);
    }

    /**
     * 批量添加
     *
     * @param list
     * @return
     */
    @Transaction
    public R<Boolean> saveBatch(List<T> list) {
        baseService.saveBatch(list);
        return success(true);
    }

    /**
     * 修改
     *
     * @param entity
     * @return
     */
    public R<Boolean> update(T entity) {
        return success(baseService.update(entity)>=1);
    }

    /**
     * 批量修改
     *
     * @param list
     * @return
     */
    @Transaction
    public R<Boolean> updateBatch(List<T> list) {
        return success(baseService.updateBatch(list).length>0);
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    public R<Boolean> delete(Serializable id) {
        return success(baseService.delete(id)>=1);
    }

    /**
     * 根据idList删除（对应的泛型是基本数据类型）
     *
     * @param idList
     * @return
     */
    @Transaction
    public R<Boolean> deleteBatch(List<String> idList) {
        return success(baseService.deleteBatch(idList)>0);
    }

    /**
     * 根据id集合查找实体列表
     * @param cls
     * @param ids
     * @return: R<List<Entity>>
     * @throws: 
     * @Date: 2023/1/7     
     */
    public List<T> listByIds(Class<?> cls, List<String> ids) {
        return baseService.listByIds(cls, ids);
    }

    @Post
    @Mapping("getDecodeParams")
    public R<String> save(Map<String, Object> params) {
        return success(SaSignUtil.addSignParamsAndJoin(params));
    }

    public File newFile(String fileName) throws IOException {
        String  filePath = File.separator + "home"+File.separator+"down"+File.separator+"temp" + File.separator;
        Set<PosixFilePermission> perms = null;
        if (SystemType.isLinux()) {
            perms = new HashSet<PosixFilePermission>();
            perms.add(PosixFilePermission.OWNER_READ);//设置所有者的读取权限
            perms.add(PosixFilePermission.OWNER_WRITE);//设置所有者的写权限
            perms.add(PosixFilePermission.OWNER_EXECUTE);//设置所有者的执行权限
            perms.add(PosixFilePermission.GROUP_READ);//设置组的读取权限
            perms.add(PosixFilePermission.GROUP_EXECUTE);//设置组的读取权限
            perms.add(PosixFilePermission.OTHERS_READ);//设置其他的读取权限
            perms.add(PosixFilePermission.OTHERS_EXECUTE);//设置其他的读取权限
        }
        File dir = new File(filePath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        if (SystemType.isLinux()) {
            Path path = Paths.get(dir.getAbsolutePath());
            Files.setPosixFilePermissions(path, perms);
        }
        File result = new File(dir.getAbsolutePath()+File.separator + fileName);
        if (SystemType.isLinux()) {
            Path path = Paths.get(result.getAbsolutePath());
            Files.setPosixFilePermissions(path, perms);
        }
        return result;
    }




//    protected <Entity> DownloadedFile downloadExcel(Context ctx, List<Entity> data, Class<Entity> cls, String fileName, String titleName) {
//        String sheetName = fileName;
//        try {
//            EasyExcel.write(ctx.outputStream(), cls).sheet("模板").doWrite(data);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        return new DownloadedFile("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", stream, "logo-new.jpg");
//    }

}
